grammar Cobol;

file                    : ( ruleLine | line)* EOF
                        ;
//----------------------------------------------------------------------------
// RULELINE
//----------------------------------------------------------------------------
ruleLine                : fdStmt
                        | moveStmt
                        ;

fdStmt                  : ( KW_FD | KW_SD ) ( OP_COMMA | OP_SEMI )? wd_ﾌｧｲﾙ名 ( KW_IS? KW_EXTERNAL | ws_文字列 )  (OP_DOT)? EOL ;
moveStmt                : KW_MOVE ( KW_CORR | KW_CORRESPONDING )? ws_move_origination KW_TO ws_move_destination  (OP_DOT)? EOL ;

ws_move_destination     : wordList ;
ws_move_origination     : wordList ;
ws_文字列               : wordList ;
wd_ﾌｧｲﾙ名               : word ;

//----------------------------------------------------------------------------
// line
//----------------------------------------------------------------------------                       
line                    : wordList EOL
                        ;
//キー区分(tblSyntax.KeyKBN) = 2:可変部分
wordList                : (word)+
                        ;
//キー区分(tblSyntax.KeyKBN) = 6:単語の可変部分 
word                    : operator
                        | literal
                        | keyword
                        | Identifier 
                        ;
//----------------------------------------------------------------------------
// KEYWORD
//----------------------------------------------------------------------------
keyword                 : KW_CORR
                        | KW_CORRESPONDING
                        | KW_EXTERNAL
                        | KW_FD
                        | KW_IS
                        | KW_MOVE
                        | KW_SD
                        | KW_TO
                        ;
KW_CORR                 : 'CORR' ;
KW_CORRESPONDING        : 'CORRESPONDING' ;
KW_EXTERNAL             : 'EXTERNAL' ;
KW_FD                   : 'FD' ;
KW_IS                   : 'IS' ;
KW_MOVE                 : 'MOVE' ;
KW_SD                   : 'SD' ;
KW_TO                   : 'TO' ;

//----------------------------------------------------------------------------
// OPERATOR
//----------------------------------------------------------------------------
operator                : OP_NOT_EQUAL2
                        | OP_DOLLAR
                        | OP_AMBER
                        | OP_LPAREN
                        | OP_LBRACK2
                        | OP_RPAREN
                        | OP_STAR
                        | OP_PLUS
                        | OP_COMMA
                        | OP_MINUS
                        | OP_DOT
                        | OP_RBRACK2
                        | OP_SLASH
                        | OP_COLON
                        | OP_ASSIGN
                        | OP_SEMI
                        | OP_LT
                        | OP_LE
                        | OP_NOT_EQUAL1
                        | OP_EQUAL
                        | OP_GT
                        | OP_GE
                        | OP_HELP
                        | OP_LBRACK
                        | OP_YEN
                        | OP_RBRACK
                        | OP_LCURLY
                        | OP_OR
                        | OP_RCURLY
                        | OP_NOT
                        ;
OP_NOT_EQUAL2           : '!=' ;
OP_DOLLAR               : '$' ;
OP_AMBER                : '&' ;
OP_LPAREN               : '(' ;
OP_LBRACK2              : '(.' ;
OP_RPAREN               : ')' ;
OP_STAR                 : '*' ;
OP_PLUS                 : '+' ;
OP_COMMA                : ',' ;
OP_MINUS                : '-' ;
OP_DOT                  : '.' ;
OP_RBRACK2              : '.)' ;
OP_SLASH                : '/' ;
OP_COLON                : ':' ;
OP_ASSIGN               : ':=' ;
OP_SEMI                 : ';' ;
OP_LT                   : '<' ;
OP_LE                   : '<=' ;
OP_NOT_EQUAL1           : '<>' ;
OP_EQUAL                : '=' ;
OP_GT                   : '>' ;
OP_GE                   : '>=' ;
OP_HELP                 : '?' ;
OP_LBRACK               : '[' ;
OP_YEN                  : '\\' ;
OP_RBRACK               : ']' ;
OP_LCURLY               : '{' ;
OP_OR                   : '|' ;
OP_RCURLY               : '}' ;
OP_NOT                  : '~' ;

//----------------------------------------------------------------------------
// Literal
//----------------------------------------------------------------------------
literal                 : numericLiteral
                        | nonnumericLiteral
                        ;
//キー区分(tblSyntax.KeyKBN) = 14:数字単語 
numericLiteral          : DecimalLiteral
                        | IntegerLiteral
                        ;
//キー区分(tblSyntax.KeyKBN) = 22:非数字単語 
nonnumericLiteral       : StringLiteral
                        | DbcsLiteral
                        | Utf8Literal
                        | HexNumber
                        | NullTerminated
                        ;
StringLiteral           : SingleQuotedString
                        | DoubleQuotedString
                        ;
DbcsLiteral             : ('G' | 'NX' | 'N') StringLiteral
                        ;
Utf8Literal             : ('UX' | 'U') StringLiteral
                        ;
HexNumber               : 'X' StringLiteral
                        ;
NullTerminated          : 'Z' StringLiteral
                        ;
IntegerLiteral          : ('+'|'-')?Digit+
                        ;
DecimalLiteral          : ('+'|'-')?Digit*('.')Digit+
                        ;
fragment
SingleQuotedString      : '\'' ('\'\'' | ~('\''))* '\''
                        ;
fragment
DoubleQuotedString      : '"' ('""' | ~('"'))* '"'
                        ;
//----------------------------------------------------------------------------
// ID
//----------------------------------------------------------------------------
//キー区分(tblSyntax.KeyKBN) = 54:ｱﾙﾌｧﾍﾞｯﾄ単語始る文字はA-Zまたはa-zの範囲内である）
Identifier              : (Alpha | '_' | Digit) (Alpha | Digit | '_' | '-')*
                        ;  
                        
fragment
Alpha                   : 'a'..'z'
                        | 'A'..'Z'
                        | '\u0080'..'\uFFFE' ~('\uFEFF') //ADDED unicode support
                        ;               
                        
fragment
Digit                   : '0'..'9'
                        ;
//----------------------------------------------------------------------------
// OTHER
//----------------------------------------------------------------------------
EOL                     : ('\r\n'|'\r'|'\n')+
                        ;
WS                      : (' '|'\t'|'\f')+ -> skip
                        ;
UnicodeBOM              : '\uFEFF' -> skip 
                        ;